let W = null
//6
class Watcher{
    constructor(data , key){
        this.data = data
        this.key = key

        W = this
        this.get()
        W = null

    }

    get(){
        return this.data[this.key]
    }

    update(){
        console.log(`${this.key}更新了 , ${this.get()}`);
    }
}


//5
class Dep{
    constructor(){
        this.subs = []
    }

    depend(watcher){
        this.subs.push(watcher)
        console.log("每次访问数据 , 就把watcher放进这个数组" , this.subs);
    }

    notify(){
        console.log("通知所有的watcher 重新加载新的数据");
        //遍历subs中的watcher 让所有的watcher调用更新视图方法
        this.subs.forEach((watcher) => {
            watcher.update();
        });
    }

}


//4.响应式核心代码
function defineReactive (data , key , value){
    observe(value)

    const dep = new Dep()

    Object.defineProperty(data , key , {
        get(){
            console.log("值被获取了");
            if(W){
                dep.depend(W)
            }
            return value
        },
        set(newValue){
            value = newValue
            console.log("值被修改了");

            dep.notify()
        }
    })
}


//3
class Observer{
    constructor(_data){
        this._data = _data

        //判断这个对象类型的数据是数组还是对象
        if(Array.isArray(this._data)){
            this.observerArr(this._data)
        }else{
            this.walk(this._data)
        }
    }

    //
    observerArr(_data){
        _data.forEach(item => observe(item))
    }

    //
    walk(_data){
        for(let key of Object.keys(_data)){
            defineReactive(_data , key , _data[key])
        }
    }
}


//2
function observe(_data){
    //判断不是对象不处理
    if(typeof _data !== "object" || _data === null) return

    //是对象类型才有资格进入响应式处理中
    new Observer(_data)

}

//1.
function Vue(options){
    this._data = options.data

    //数据代理
    for(let key of Object.keys(this._data)){
        Object.defineProperty(this , key , {
            get(){
                //读vm上的属性的时候
                return this._data[key]
            },
            set(newValue){
                this._data[key] = newValue
            }
        })
    }


    //这才开始真正的响应式操作
    observe(this._data)
}

const vm = new Vue({
    data:{
        count: 1,
        person:{
            name:"老六",
            age: 18
        }
    }
})

// console.log(vm);

function huoqu(){
    new Watcher(vm , "count")
    new Watcher(vm , "count")
    new Watcher(vm , "person")
}

function shezi(){
    vm.count = 2
}

huoqu()
shezi()